package ar.com.sectorwine.services;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.NonUniqueObjectException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import ar.com.sectorwine.entities.Empresa;
import ar.com.sectorwine.entities.Stock;
import ar.com.sectorwine.entities.Users;
import ar.com.sectorwine.repository.EmpresaRepository;
import ar.com.sectorwine.repository.EmpresasDAO;
import ar.com.sectorwine.repository.UsuariosDAO;
import excepciones.ExcepcionGeneral;

/**
 * @author Ismael
 * 
 */
@Service
@Transactional(propagation = Propagation.MANDATORY)
public class EmpresasServiceImpl implements EmpresasService {

	@Autowired
	EmpresasDAO empresasDAO;
	@Autowired
	UsuariosDAO usuariosDAO;
	@Autowired
	EmpresaRepository empresaRepository;

	private static final Logger logger = LoggerFactory
			.getLogger(EmpresasServiceImpl.class);

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void crearEmpresa(Empresa empresa, Users user)
			throws ExcepcionGeneral {
		try {

			Map<String, String> map = new HashMap<String, String>();
			map.put("razonSocial", empresa.getRazonSocial());

			if (!empresasDAO.findByAttributes(map).isEmpty()) {
				throw new ExcepcionGeneral(
						"La empresa '"
								+ empresa.getRazonSocial()
								+ "' ya existe <a class='aclaracion_blanco' href='#'>(visitar perfil)<//a>");
			}
			Map<String, String> map2 = new HashMap<String, String>();
			map2.put("cuit", empresa.getCuit());

			if (!empresasDAO.findByAttributes(map2).isEmpty()) {
				throw new ExcepcionGeneral(
						"El CUIT ingresado '"
								+ empresa.getCuit()
								+ "' ya esta registrado <a class='aclaracion_blanco' href='#'>(visitar perfil)<//a>");
			}
			empresa.setFechaCreacion(new Date());
			empresa.setProductos(new ArrayList<Stock>());
			user.getPerfilUsuario().getEmpresas().add(empresa);
			usuariosDAO.update(user);
			logger.info("EMPRESA CREADA");
		} catch (NonUniqueObjectException e) {
			logger.error(e.getMessage());
			throw new ExcepcionGeneral(
					"La empresa que esta queriendo crear ya existe.");
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Empresa> getEmpresas() {
		List<Empresa> listaEmpresas = empresasDAO.findAll();
		logger.info("EMPRESAS ENCONTRADAS");
		return listaEmpresas;
	}

	/**
	 * {@inheritDoc}
	 */
	public Empresa getEmpresa(String id) {
		Long idEmpresa = Long.parseLong(id);
		Empresa empresa = empresasDAO.findOne(idEmpresa);
		logger.info("EMPRESA ENCONTRADA");
		return empresa;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void modificarEmpresa(Empresa empresa) throws ExcepcionGeneral {
		try {
			boolean error = false;
			Map<String, String> map = new HashMap<String, String>();
			map.put("razonSocial", empresa.getRazonSocial());
			List<Empresa> empresas = empresasDAO.findByAttributes(map);
			if (!empresas.isEmpty() && (empresas.size() < 2)) {
				error = !empresas.get(0).getId().equals(empresa.getId());
				if (error) {
					throw new ExcepcionGeneral(
							"La empresa '"
									+ empresa.getRazonSocial()
									+ "' ya existe <a class='aclaracion_blanco' href='#'>(visitar perfil)<//a>");
				}
			}

			Map<String, String> map2 = new HashMap<String, String>();
			map2.put("cuit", empresa.getCuit());
			empresas = empresasDAO.findByAttributes(map2);
			if (!empresas.isEmpty() && (empresas.size() < 2)) {
				error = !empresas.get(0).getId().equals(empresa.getId());
				if (error) {
					throw new ExcepcionGeneral(
							"La cuit '"
									+ empresa.getCuit()
									+ "' ya esta registrado <a class='aclaracion_blanco' href='#'>(visitar perfil)<//a>");
				}
			}
			empresasDAO.update(empresa);
			logger.info("EMPRESA MODIFICADA");
		} catch (NonUniqueObjectException e) {
			logger.error(e.getMessage());
			throw new ExcepcionGeneral("Error al intentar modificar la empresa");
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean bajaEmpresa(String id) {
		try {
			Long idEmpresa = Long.parseLong(id);
			Empresa empresaMod = empresasDAO.findOne(idEmpresa);
			empresaMod.setBaja(true);
			empresasDAO.update(empresaMod);
			logger.info("EMPRESA DADA DE BAJA");
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void seguirEmpresa(Users usuario, Empresa empresa) {

		usuario.getPerfilUsuario().getEmpresasSeguidas().add(empresa.getId());

		boolean esSeguidor = false;
		 
		for (Users u : empresa.getSeguidores()) {

			esSeguidor |= u.getUsername().equals(usuario.getUsername());
			
		}

		if (!esSeguidor) {
			empresa.getSeguidores().add(usuario);
		}

		usuariosDAO.update(usuario);
		empresasDAO.update(empresa);

	}

	@Override
	public void dejarDeSeguirEmpresa(Users usuario, Empresa empresa) {

		usuario.getPerfilUsuario().getEmpresasSeguidas().remove(empresa.getId());

		empresa.getSeguidores().remove(usuario);

		usuariosDAO.update(usuario);
		empresasDAO.update(empresa);

	}

	@Override
	public List<Empresa> buscarEmpresa(String razonSocial) {

		return empresaRepository.findByRazonSocialLike("%" + razonSocial + "%");
	}

}
